"""
读写文件是最常见的IO操作。Python内置了读写文件的函数，用法和C是兼容的。

读写文件前，我们先必须了解一下，在磁盘上读写文件的功能都是由操作系统提供的，现代操作系统不允许普通的程序直接操作磁盘，
所以，读写文件就是请求操作系统打开一个文件对象（通常称为文件描述符），然后，通过操作系统提供的接口从这个文件对象中读取数据（读文件），
或者把数据写入这个文件对象（写文件）。
"""
file_adr = '../../min-cut/data.txt'
print("-" * 10 + "normal read" + "-" * 10)
f = open(file_adr, 'r')
read = f.read()
print(read)
f.close()

"""
由于文件读写时都有可能产生IOError，一旦出错，后面的f.close()就不会调用。
所以，为了保证无论是否出错都能正确地关闭文件，我们可以使用try ... finally来实现
但是Python引入了with语句来自动帮我们调用close()方法
这和前面的try ... finally是一样的，但是代码更佳简洁，并且不必调用f.close()方法

with as 语法：
with expression [as target]：
    代码块

参数说明：
expression：是一个需要执行的表达式；
target：是一个变量或者元组，存储的是expression表达式执行返回的结果，可选参数

open函数，第一个实参是文件名字符串。第二个实参mode是包含描述文件使用方式字符的字符串。
mode 的值包括 'r' ，表示文件只能读取；'w' 表示只能写入（现有同名文件会被覆盖）；
'a' 表示打开文件并追加内容，任何写入的数据会自动添加到文件末尾。
'r+' 表示打开文件进行读写。mode 实参是可选的，省略时的默认值为 'r'。
"""
print('-' * 10 + 'with as read' + '-' * 10)
with open('../../min-cut/data.txt', 'r') as f:
    for line in f.readlines():
        print(line.replace('1', '2').strip())  # 把末尾的'\n'删掉
    print('-' * 10)
    """
    Python 文件操作中,有一个玩意叫做指针，本名seek
    file对象,有个方法叫seek(),用来调整文件指针位置,而在我们读取一次后,指针指向EOF(文件末尾),再次读取当然是空字符串啦.
    """
    f.seek(1)  # 重置指针的位置为1，则跳过首个字符
    print(f.read())

"""
在 python 中，为了避免读写与数据库连接等占据资源且需要释放的资源管理操作，使用 with as 语句操作上下文管理器（context manager），
它能够帮助我们自动分配并且释放资源。
简单的理解，同时包含 __enter__() 和 __exit__() 方法的对象就是上下文管理器。
常见构建上下文管理器的方式有 2 种，分别是基于类实现和基于生成器实现。
with通过__enter__方法初始化，然后在__exit__中做善后以及处理异常。
所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。
其中__enter__()方法在语句体（with语句包裹起来的代码块）执行之前进入运行，__exit__()方法在语句体执行完毕退出后运行。
with 语句适用于对资源进行访问的场合，确保不管使用过程中是否发生异常都会执行必要的“清理”操作，释放资源，
比如文件使用后自动关闭、线程中锁的自动获取和释放等。
使用 with as 操作已经打开的文件对象（本身就是上下文管理器），无论期间是否抛出异常，都能保证 with as 语句执行完毕后，
自动关闭已经打开的文件。
"""
